package com.feidee.data.report.dao.impl;

import com.alibaba.fastjson.JSONObject;
import com.feidee.data.report.dao.IRedisDao;
import com.feidee.data.report.model.FunnelResult;
import com.feidee.data.report.util.SerializeUtil;
import com.feidee.fdcommon.configuration.CustomConfiguration;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisSentinelPool;
import redis.clients.util.Pool;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class RedisDaoImpl implements IRedisDao {
	private static Logger logger;
	private Jedis jedis;
	private static Pool<Jedis> jedisPool;

	static {
		logger = Logger.getLogger(RedisDaoImpl.class);
		JedisPoolConfig config = new JedisPoolConfig();
		//最大分配的对象数
		config.setMaxTotal(1024);
		//最大能够保持idel状态的对象数
		config.setMaxIdle(200);
		//当池内没有返回对象时，最大等待时间
		config.setMaxWaitMillis(1000);
		//当调用borrow Object方法时，是否进行有效性检查
		config.setTestOnBorrow(false);
		//当调用create Object方法时，是否进行有效性检查
		config.setTestOnCreate(true);
		//当调用return Object方法时，是否进行有效性检查
		config.setTestOnReturn(true);

		//初始化查询缓存Redis连接池
		if (StringUtils.isNotBlank(CustomConfiguration.getString("redis.pwd", "feb20_d8c7dbd5_70fe0c0H65bdd"))) {
			jedisPool = new JedisPool(config,
					CustomConfiguration.getString("redis.server", "rept.dsjfeideedba.com"),
					CustomConfiguration.getInt("redis.port", 9400),
					500000,
					CustomConfiguration.getString("redis.pwd", "feb20_d8c7dbd5_70fe0c0H65bdd"));
		} else {
			jedisPool = new JedisPool(config,
					CustomConfiguration.getString("redis.server", "rept.dsjfeideedba.com"),
					CustomConfiguration.getInt("redis.port", 9400),
					500000);
		}
		logger.info("Redis初始化 Redis host:" + CustomConfiguration.getString("redis.server") +
				",port:" + CustomConfiguration.getString("redis.port") +
				",pwd:" + CustomConfiguration.getString("redis.pwd") +
				",Pool:" + jedisPool);
	}

	@Override
	public List<FunnelResult> queryFunnelResult(String key) {
		List<FunnelResult> funnelResultList = null;
		try {
			funnelResultList = (List<FunnelResult>) getList(key);
		} catch (Exception e) {
			logger.error("Key为: " + key + " 查询redis失败", e);
		}
		return funnelResultList;
	}

	@Override
	public Map<Map<String, JSONObject>, Map<String, JSONObject>> queryRealTimeReportResult(String key) {
		Map<Map<String, JSONObject>, Map<String, JSONObject>> realTimeReportResult = null;
		try {
			realTimeReportResult = (Map<Map<String, JSONObject>, Map<String, JSONObject>>) getMap(key);
		} catch (Exception e) {
			logger.error("Key为: " + key + " 查询redis失败", e);
		}
		return realTimeReportResult;
	}

	@Override
	public void insertList(String key, List<?> list) {
		setList(key, list);
	}

	@Override
	public void insertListWithLife(String key, List<?> list, int lifeTime) {
		setListWithLife(key, list, lifeTime);
	}

	@Override
	public void insertMap(String key, Map<?, ?> map) {
		setMap(key, map);
	}

	@Override
	public void insertMapWithLife(String key, Map<?, ?> map, int lifeTime) {
		setMapWithLife(key, map, lifeTime);
	}

	/**
	 * 设置List集合,带有生命周期
	 *
	 * @param key
	 * @param list
	 * @param lifeTime
	 */
	public void setListWithLife(String key, List<?> list, int lifeTime) {
		try {
			jedis = jedisPool.getResource();
			if (list != null && !list.isEmpty()) {
				jedis.setex(key.getBytes(), lifeTime, SerializeUtil.serializeList(list));
			} else {//如果list为空,则设置一个空
				jedis.setex(key.getBytes(), lifeTime, "".getBytes());
			}
			logger.info("redis key: " + key + " 有过期缓存成功");
		} catch (Exception e) {
			logger.error("redis key: " + key + " 有过期缓存失败", e);
		} finally {
			if (jedis != null) {
				try {
					jedis.close();
				} catch (Exception e) {
					logger.error("redis 归还连接到资源池失败!",e);
				}
			}
		}
	}

	/**
	 * 设置List集合
	 *
	 * @param key
	 * @param list
	 */
	public void setList(String key, List<?> list) {
		try {
			jedis = jedisPool.getResource();
			if (list != null && !list.isEmpty()) {
				jedis.set(key.getBytes(), SerializeUtil.serializeList(list));
			} else {//如果list为空,则设置一个空
				jedis.set(key.getBytes(), "".getBytes());
			}
			logger.info("redis key: " + key + " 无过期缓存成功");
		} catch (Exception e) {
			logger.error("Key为: " + key + " 无过期缓存失败", e);
		} finally {
			if (jedis != null) {
				try {
					jedis.close();
				} catch (Exception e) {
					logger.error("redis 归还连接到资源池失败!",e);
				}
			}
		}
	}

	/**
	 * 从redis获取List集合
	 *
	 * @param key
	 * @return
	 */
	public List<?> getList(String key) {
		byte[] data = null;
		try {
			jedis = jedisPool.getResource();
			if (jedis == null || !jedis.exists(key)) {
				return null;
			}
			data = jedis.get(key.getBytes());
		} catch (Exception e) {
			logger.error("Key为: " + key + " 查询redis失败", e);
		} finally {
			if (jedis != null) {
				try {
					jedis.close();
				} catch (Exception e) {
					logger.error("redis 归还连接到资源池失败!",e);
				}
			}
		}
		return SerializeUtil.unserializeList(data);
	}

	/**
	 * 设置Map集合
	 *
	 * @param key
	 * @param map
	 */
	public void setMap(String key, Map<?, ?> map) {
		try {
			jedis = jedisPool.getResource();
			if (map != null && !map.isEmpty()) {
				jedis.set(key.getBytes(), SerializeUtil.serialize(map));
			} else {//如果map为空,则设置一个空
				jedis.set(key.getBytes(), "".getBytes());
			}
			logger.info("redis key: " + key + " 无过期缓存成功");
		} catch (Exception e) {
			logger.error("redis key为: " + key + " 无过期缓存失败", e);
		} finally {
			if (jedis != null) {
				try {
					jedis.close();
				} catch (Exception e) {
					logger.error("redis 归还连接到资源池失败!",e);
				}
			}
		}
	}

	/**
	 * 从redis获取Map集合
	 *
	 * @param key
	 * @return
	 */
	public Map<?, ?> getMap(String key) {
		byte[] data = null;
		try {
			jedis = jedisPool.getResource();
			if (jedis == null || !jedis.exists(key)) {
				return null;
			}
			data = jedis.get(key.getBytes());
		} catch (Exception e) {
			logger.error("Key为: " + key + " 查询redis失败", e);
		} finally {
			if (jedis != null) {
				try {
					jedis.close();
				} catch (Exception e) {
					logger.error("redis 归还连接到资源池失败!",e);
				}
			}
		}
		return (Map<?, ?>) SerializeUtil.deserialize(data);
	}

	/**
	 * 设置Map集合,带有生命周期
	 *
	 * @param key
	 * @param map
	 * @param lifeTime
	 */
	public void setMapWithLife(String key, Map<?, ?> map, int lifeTime) {
		try {
			jedis = jedisPool.getResource();
			if (map != null && !map.isEmpty()) {
				jedis.setex(key.getBytes(), lifeTime, SerializeUtil.serialize(map));
			} else {//如果map为空,则设置一个空
				jedis.setex(key.getBytes(), lifeTime, "".getBytes());
			}
			logger.info("redis key: " + key + " 有过期缓存成功");
		} catch (Exception e) {
			logger.error("redis key: " + key + " 有过期缓存失败", e);
		} finally {
			if (jedis != null) {
				try {
					jedis.close();
				} catch (Exception e) {
					logger.error("redis 归还连接到资源池失败!",e);
				}
			}
		}
	}
}
